package online.inote.naruto.api.access.admin.common.configure;

import com.alibaba.fastjson.JSON;
import lombok.extern.log4j.Log4j2;
import online.inote.naruto.api.access.admin.common.props.ApiAdminProperties;
import online.inote.naruto.api.access.jwt.JwtHelper;
import online.inote.naruto.cache.CacheSupport;
import online.inote.naruto.common.utils.response.ExtendResponse;
import online.inote.naruto.common.utils.response.Response;
import online.inote.naruto.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

/**
 * @description 登录处理
 * @author XQF.Sui
 * @date 2021/08/14 16:42
 */
@Log4j2
public class LoginInterceptor implements HandlerInterceptor {

  private static final String HEADER_TOKEN_KEY = "naruto-token";

  @Autowired private ApiAdminProperties props;

  @Override
  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
      throws Exception {

    if (handler instanceof HandlerMethod) {
      String token = request.getHeader(HEADER_TOKEN_KEY);

      if (StringUtils.isBlank(token)) {
        log.info("请求无token信息，禁止访问");
        returnError(response, ExtendResponse.fail("请求无token信息，禁止访问"));
        return false;
      }

      return checkToken(token);
    }

    return HandlerInterceptor.super.preHandle(request, response, handler);
  }

  @Override
  public void afterCompletion(
      HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
      throws Exception {
    String token = request.getHeader(HEADER_TOKEN_KEY);

    if (StringUtils.isNotBlank(token)) {
      String id = JwtHelper.getClaims(token).getBody().getId();
      CacheSupport.expire(props.getCache().getCacheKeyPrefix() + id, 1800);
    }
  }

  private boolean checkToken(String token) {
    String id = JwtHelper.getClaims(token).getBody().getId();
    String cacheToken = CacheSupport.get(props.getCache().getCacheKeyPrefix() + id);
    return StringUtils.equals(token, cacheToken);
  }

  private void returnError(HttpServletResponse response, Response<Object> result) {
    response.setCharacterEncoding(StandardCharsets.UTF_8.toString());
    response.setContentType(MediaType.APPLICATION_JSON_VALUE);

    try {
      response.getWriter().print(JSON.toJSONString(result));
    } catch (IOException e) {
      log.error("response error", e);
    }
  }
}
